﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;

namespace Sgr.Exceptions
{
    /// <summary>
    /// 领域内部异常信息
    /// </summary>
    [Serializable]
    public class DomainException : Exception
    {
        /// <summary>
        /// 错误类型
        /// </summary>
        public DomainErrorType ErrorType { get; }

        /// <summary>
        /// 错误代码
        /// </summary>
        public string? ErrorCode { get; }

        /// <summary>
        /// 附加数据
        /// </summary>
        public object? AdditionalData { get; }

        /// <summary>
        /// 创建领域异常实例
        /// </summary>
        public DomainException() : base() { }

        /// <summary>
        /// 创建领域异常实例
        /// </summary>
        /// <param name="message">错误消息</param>
        public DomainException(string? message) : base(message)
        {
            ErrorType = DomainErrorType.Validation;
        }

        /// <summary>
        /// 创建领域异常实例
        /// </summary>
        /// <param name="message">错误消息</param>
        /// <param name="innerException">内部异常</param>
        public DomainException(string? message, Exception? innerException)
            : base(message, innerException)
        {
            ErrorType = DomainErrorType.Validation;
        }

        /// <summary>
        /// 创建领域异常实例
        /// </summary>
        /// <param name="errorType">错误类型</param>
        /// <param name="message">错误消息</param>
        public DomainException(DomainErrorType errorType, string? message)
            : base(message)
        {
            ErrorType = errorType;
        }

        /// <summary>
        /// 创建领域异常实例
        /// </summary>
        /// <param name="errorType">错误类型</param>
        /// <param name="message">错误消息</param>
        /// <param name="errorCode">错误代码</param>
        /// <param name="additionalData">附加数据</param>
        public DomainException(DomainErrorType errorType, string? message, string? errorCode = null, object? additionalData = null)
            : base(message)
        {
            ErrorType = errorType;
            ErrorCode = errorCode;
            AdditionalData = additionalData;
        }

        /// <summary>
        /// 创建领域异常实例
        /// </summary>
        /// <param name="errorType">错误类型</param>
        /// <param name="message">错误消息</param>
        /// <param name="innerException">内部异常</param>
        /// <param name="errorCode">错误代码</param>
        /// <param name="additionalData">附加数据</param>
        public DomainException(DomainErrorType errorType, string? message, Exception? innerException, string? errorCode = null, object? additionalData = null)
            : base(message, innerException)
        {
            ErrorType = errorType;
            ErrorCode = errorCode;
            AdditionalData = additionalData;
        }

        /// <summary>
        /// 创建数据验证失败异常
        /// </summary>
        public static DomainException ValidationError(string message, string? errorCode = null, object? additionalData = null)
            => new DomainException(DomainErrorType.Validation, message, errorCode, additionalData);

        /// <summary>
        /// 创建状态冲突异常
        /// </summary>
        public static DomainException ConflictError(string message, string? errorCode = null, object? additionalData = null)
            => new DomainException(DomainErrorType.Conflict, message, errorCode, additionalData);

        /// <summary>
        /// 创建资源未找到异常
        /// </summary>
        public static DomainException NotFoundError(string message, string? errorCode = null, object? additionalData = null)
            => new DomainException(DomainErrorType.NotFound, message, errorCode, additionalData);

        /// <summary>
        /// 创建超出业务限制异常
        /// </summary>
        public static DomainException LimitExceededError(string message, string? errorCode = null, object? additionalData = null)
            => new DomainException(DomainErrorType.LimitExceeded, message, errorCode, additionalData);
    }

    public enum DomainErrorType
    {
        /// <summary>
        /// 数据校验失败
        /// </summary>
        Validation,

        /// <summary>
        /// 状态冲突
        /// </summary>
        Conflict,

        /// <summary>
        /// 资源未找到
        /// </summary>
        NotFound,

        /// <summary>
        /// 超出业务限制
        /// </summary>
        LimitExceeded
    }
}